<?php

declare(strict_types=1);

namespace App\Lib\WeApp\Support\Abstract;

use App\Lib\Classes\Xml;
use App\Lib\WeApp\Support\Traits\HasAttributesTrait;
use ArrayAccess;

/**
 * @property string $FromUserName
 * @property string $ToUserName
 * @property string $Encrypt
 *
 * @implements ArrayAccess<array-key, mixed>
 */
abstract class MessageAbstract implements \JsonSerializable, ArrayAccess
{
    use HasAttributesTrait;

    /**
     * @param  array<string,string>  $attributes
     */
    final public function __construct(array $attributes = [], protected ?string $originContent = '')
    {
        $this->attributes = $attributes;
    }

    /**
     * @throws \Exception
     */
    public static function createFromRequest($request): MessageAbstract
    {
        $attributes = self::format($originContent = strval($request->getContent()));

        return new static($attributes, $originContent);
    }

    /**
     * @return array<string,string>
     *
     * @throws \Exception
     */
    public static function format(string $originContent): array
    {
        if (stripos($originContent, '<') === 0) {
            $attributes = Xml::parse($originContent);
        }

        // Handle JSON format.
        $dataSet = json_decode($originContent, true);

        if (json_last_error() === JSON_ERROR_NONE && $originContent) {
            $attributes = $dataSet;
        }

        if (empty($attributes) || ! is_array($attributes)) {
            return [];
//            throw new \Exception('Failed to decode request contents.');
        }

        return $attributes;
    }

    public function getOriginalContents(): string
    {
        return $this->originContent ?? '';
    }

}
